package cn.yr.netty.handler;

import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @author Lang 1102076808@qq.com
 * @description
 * @date 2021-01-07 22:59
 */
@Component
public class NettyWebSocketHandlerInitializer extends ChannelInitializer<Channel> {

	@Autowired
	private NettyMessageHandler nettyMessageHandler;
	@Autowired
	private NettyServerHandler nettyServerHandler;

	@Override
	protected void initChannel(Channel ch) {
		// 获得 Channel 对应的 ChannelPipeline
		ChannelPipeline channelPipeline = ch.pipeline();
		// 添加一堆 NettyServerHandler 到 ChannelPipeline 中
		channelPipeline
				//因为基于http协议，使用http的编码和解码器
				.addLast(new HttpServerCodec())
				/*
	                说明
	                1. http数据在传输过程中是分段, HttpObjectAggregator ，就是可以将多个段聚合
	                2. 这就就是为什么，当浏览器发送大量数据时，就会发出多次http请求
                 */
				.addLast(new HttpObjectAggregator(65536))
				//是以块方式写，添加ChunkedWriteHandler处理器
				.addLast(new ChunkedWriteHandler())
				/*
                    说明
                    1. 对应websocket ，它的数据是以 帧(frame) 形式传递
                    2. 可以看到WebSocketFrame 下面有六个子类
                    3. 浏览器请求时 ws://localhost:7000/hello 表示请求的uri
                    4. WebSocketServerProtocolHandler 核心功能是将 http协议升级为 ws协议 , 保持长连接
                    5. 是通过一个 状态码 101
                 */
				.addLast(new WebSocketServerProtocolHandler("/im"))
				// 消息分发器
				.addLast(nettyMessageHandler)
				// 服务端处理器
				.addLast(nettyServerHandler);
	}
}
